Home |
| Latest | About | Random
# Week 1 Friday Dear Class, A new homework has been posted, tentatively due next Thursday. It uses today's ideas directly. **Please finish reading section 5 by next Monday.** Next week we start the `string` class (section 6). You got this! -- B. ## Today's mystery: why is 17 out of 20 equal to 0%? Imagine in one of your classes the Professor ran a program that computes a quiz percentage for you as follows. Don't run it yet. What do you expect it to print for 17 out of 20? ```cpp #include using namespace std; int main(){ int correct, total; cout << "How many questions did you get right? "; cin >> correct; cout << "How many questions were there? "; cin >> total; cout << "Your score is " << correct / total * 100 << "%."; return 0; } ``` - `cin >> x;` is how a program asks for input: it **pauses** until the user types a value and hits enter, then stores it in `x`. The arrow points *into* the variable, the opposite direction of `cout <<`, which sends data *out* to the screen. `std::cin` is part of the `` header. - Run it with `17` and `20`. It prints `0%`. Try `20` and `20`: it prints `100%`. Any score below perfect prints `0%`. By the end of today you will know why, and you will know three ways to fix it. ## Integer division: `/` and `%` **Ask yourself first.** What do you think `17 / 5` gives? - Is it A: `3.4`, B: `3`, or C: `4`? - And what about `17 % 5`? With two `int`s, `/` and `%` work like grade school division with remainder. Picture 17 people and buses that each can hold 5 people: - `17 / 5` is `3`, the number of **full buses**.This is the quotient. - `17 % 5` is `2`, the **people left over**. This is the remainder. The fraction part of `/` is thrown away. Both results are `int`s. ![[1-teaching/ucla-2026-fall-pic-10a/---files/17div5.png]] **Some applications.** - *Splitting digits.* Suppose you have a 3-digit number `137`, what could you do to split it into the first two-digit `13` and the last digit `7`? - *Making change.* You owe someone 87 cents. How many quarters and how many cents left over? Can you figure out how many dimes fit in the remaining cents? **Two more facts:** - Dividing by `0` is **undefined behavior**: the language makes no promise about what happens (a crash, junk, anything). On most machines with `int`s, the program crashes. Try it at home. - Negative numbers follow a sign rule:   - `X / Y` has a sign that is the correct mathematical sign.   - `X % Y` has a sign that matches `X`. So `%` can give negative numbers!   - `(X / Y)  * Y + (X % Y)` always equals `X`. Shortcuts: `i /= j` means `i = i / j`, and `i %= j` means `i = i % j`. **Back to the mystery.** What is `17 / 20`? Both are `int`s, so the fraction `0.85` is thrown away and the answer is `0`. Then `0 * 100` is `0`. That is *why* we got `0%`. Fixing it needs decimals and a new tool and idea called **casting**, which we get to in Part 5. ## Decimals: `double` `int`s can't hold `3.14`. A `double` can. A literal with a decimal point, like `0.`, `0.0`, or `3.14159`, is a `double`. ```cpp #include using namespace std; int main(){ const double PI = 3.14159; double r; cout << "Give a radius: "; cin >> r; cout << "The area is " << PI * r * r; return 0; } ``` (`const` means the value can never change after it is set. It protects `PI` from accidents.) - `+ - * /` work on `double`s. Try `+=` and `%` and see what happens. - Dividing by `0.0` is also undefined behavior (some compilers give `inf`). Need r to the 100th power? Don't type `r * r * ...` a hundred times. The function `pow(r, 100)` does it, and it lives in the `` header. When you need a function, you look it up on [cppreference.com](https://cppreference.com/). You will practice that later in Task B. ## Decimals are not exact One warning before we use `double` everywhere. **Predict.** Is `0.1 + 0.1 + 0.1` equal to `0.3`? By default `cout` shows only about 6 digits. The manipulator `setprecision(17)` from `` asks for 17, so we can see what is really stored. ```cpp #include #include using namespace std; int main(){ double a = 0.1; double c = 0.3; cout << setprecision(17); cout << a << endl; cout << c << endl; cout << a + a + a << endl; // ?? cout << 20.15 * 100 << endl; // ?? return 0; } ``` The computer stores `double`s in binary, and `0.1` has no exact binary form, just as `1/3` has no exact decimal form (`0.3333...`). - A `double` keeps about 15 to 17 significant digits and rounds the rest. - `int`s are finite too (about plus or minus 2 billion). **For money**, real programs avoid `double` and store whole cents in an `int`. In case `double` is unavoidable, then *rounding* can sometimes help. ## Fixing the mystery: casting We know `17 / 20` is `0` because both are `int`s. To get `0.85`, at least one side must be a `double` before the division happens. **Task A. Try it!** Then compare with these three fix proposals: - `static_cast(correct) / total * 100`. This **casts** `correct` into a `double` first, so the division is a `double` division. - `100.0 * correct / total`. Here `100.0 * correct` becomes a `double` before the division happens. - `correct * 100 / total`. This one stays in `int`, so it avoids the zero, but it still **truncates**. Try `7` out of `9`: you get `77`, **not** `77.7778`. **Casting rules:** - `static_cast(n)` turns an `int n` into a `double`. - `static_cast(x)` turns a `double x` into an `int` by **truncating** (chopping the decimals), not rounding. If you want rounding, use the `round` function (you will look it up in Task B). **Task B. Round to one decimal place.** Store the percentage in a `double score`, then print it rounded to one decimal place (`77.7778` becomes `77.8`). You need a rounding function, so look it up on [cppreference.com](https://cppreference.com/) and answer: - What is the function called? - Which header does it need? - What does it take in, and what does it return? Then work out how to get *one decimal place* out of it. (If you're stuck: multiply first, round, then divide.) **Double-check.** The volume of a sphere of radius `r` is $\frac{4}{3}\pi r^{3}$. Is there a bug using this C++ code ```cpp 4 / 3 * PI * pow(r, 3) ``` to calculate the volume of a sphere of radius `r`? Assume here we already have `double PI = 3.14159;` and `double r;` ### Implicit casting: Operations mixing `double` and `int` (the reading covers the details) - `int` with `int` stays `int`. `double` with `double` stays `double`. - Mixing an `int` with a `double` makes the result a `double`. - Assigning a `double` to an `int` variable truncates: `double a = 1.9; int b = a;` makes `b` equal to `1`. - Assigning an `int` to a `double` variable is safe. Even when C++ does this automatically, it is better practice to write the cast yourself to show your intent. ## `%` is a clock 13 o'clock is 1 o'clock, because `13 % 12 == 1`. Whenever something repeats in a cycle, `%` is the tool: days of the week, hours, turns in a game. If you keep adding 1 to `x`, then `x % 7` cycles `0, 1, 2, 3, 4, 5, 6, 0, 1, ...`. **Example F. Usefulness of this `%`.** Encode `0` as Sunday, `1` as Monday, ..., `6` as Saturday. **Suppose today is Friday.** - Which day is it... - after 3 days? - after 10 days? - after 3000 days? - 10 days *before*? - How many weeks are in 3000 days? ```cpp #include using namespace std; int main(){ int day = 5; // Friday // Finish this. Hint: / and % are both useful. return 0; } ``` - In case `%` gives you negative, you can add to it the length of the cycle to make it positive. ## Recap Three things to remember from today: 1. `int / int` throws the fraction away. Cast to `double` *before* dividing. 2. A `double` is an approximation. Don't expect `0.1 + 0.1 + 0.1` to equal `0.3`. 3. `%` gives the remainder, and it cycles, so use it for anything that repeats. ## One last thing: `++` and `--` Since it's Friday, let's end the week with the name of the language itself. `x++` adds 1 to `x`. This is where `C++` got its name: a pun on `C = C + 1`, meaning "C, but one better." Which means that, after this week, ```cpp week++; ``` See you Monday! **Example D (if there is time, or try it at home).** `x++` and `++x` both add 1, but they hand back different values. Predict every line before you run it: ```cpp #include using namespace std; int main(){ int x = 0; cout << x++ << endl; cout << x << endl; x = 0; cout << ++x << endl; cout << x << endl; return 0; } ``` The rule: - `x++` (post-increment): hand back a copy of the old value, *then* add 1. - `++x` (pre-increment): add 1, *then* hand back the new value. - `x--` and `--x` work the same way with subtraction. A standalone `x++;` is fine. Mixing `x++` inside a bigger expression is a classic source of bugs, so avoid it. --- Please finish reading the rest of **Section 5**, get started and try HW1, and read ahead in **Section 6.** Come to any of our office hours for questions! I'll see you next Monday!